package br.com.rapidrest.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodInvoker {

	private Method method;

	public MethodInvoker(Method method) {
		this.method = method;
	}

	public Object invoke(Object target, String[] params)
			throws NoSuchMethodException, InstantiationException,
			IllegalAccessException, InvocationTargetException {
		Class<?>[] parameterTypes = method.getParameterTypes();
		Object[] convertedObjects = new Object[parameterTypes.length];
		for (int i = 0; i < parameterTypes.length; i++) {
			Class<?> paramType = parameterTypes[i];
			if (paramType.isEnum()) {
				convertedObjects[i] = instantiateEnum(paramType, params[i]);
			} else {
				convertedObjects[i] = instantiate(paramType, params[i]);
			}
		}
		return method.invoke(target, convertedObjects);
	}

	private Object instantiate(Class<?> type, String value)
			throws SecurityException, NoSuchMethodException,
			IllegalArgumentException, InstantiationException,
			IllegalAccessException, InvocationTargetException {
		Constructor<?> constructor = type.getConstructor(String.class);
		return constructor.newInstance(value);
	}

	@SuppressWarnings("unchecked")
	private Object instantiateEnum(Class type, String value) {
		return Enum.valueOf(type, value);
	}

}